package com.troubadorian.feeds;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import com.troubadorian.feeds.R;
import com.troubadorian.feeds.Callback;
import com.troubadorian.feeds.NavigationDrawerActivity.PlanetFragment;
import com.troubadorian.feeds.helpers.FlipView;
import com.troubadorian.feeds.helpers.OverFlipMode;
import com.troubadorian.feeds.helpers.FlipView.OnFlipListener;
import com.troubadorian.feeds.helpers.FlipView.OnOverFlipListener;
import com.troubadorian.feeds.models.FlickrPhotoResponse;
import com.troubadorian.feeds.models.Item;
import com.troubadorian.feeds.models.Photo;
import com.troubadorian.feeds.models.PhotosHashMap;
import com.troubadorian.feeds.models.Photo.PhotoSize;
import com.troubadorian.feeds.utils.ImageCacheLoader;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements Callback, OnFlipListener,
		OnOverFlipListener
{

	/*
	 * Navigation Drawer properties
	 */

	private DrawerLayout mDrawerLayout;
	private ListView mDrawerList;
	private ActionBarDrawerToggle mDrawerToggle;

	private CharSequence mDrawerTitle;
	private CharSequence mTitle;
	private String[] mPlanetTitles;
	private int mPosition;

	/*
	 * Other code
	 */

	private FlipView mFlipView;
	private FlipAdapter mAdapter;
	private List<Item> items = new ArrayList<Item>();
	private ImageCacheLoader imageCacheLoader;
	private ProgressDialog mProgressBar;
	private List<Photo> mListOfPhotos = new ArrayList<Photo>();
	private List<com.fivehundredpixels.fivehundredpixels.models.Photo> my500pxList = new ArrayList<com.fivehundredpixels.fivehundredpixels.models.Photo>();
	private FlickrPhotoResponse mFlickrPhotoResponse;
	private List<Bitmap> mPhotoBitmapList = new ArrayList<Bitmap>();
	private PhotosHashMap<Photo, Bitmap> mMap = new PhotosHashMap<Photo, Bitmap>(
			15, 0.75f, false);

	private static final String TAG = "MainActivity";

	public class FlipAdapter extends BaseAdapter implements OnClickListener
	{

		private LayoutInflater inflater;
		private Callback callback;

		public FlipAdapter(Context context)
		{
			inflater = LayoutInflater.from(context);
			// for (int i = 0; i < 10; i++)
			// {
			// items.add(new Item(i, "Coffee", "Drinks"));
			// }
			/*
			 * for (Photo p : mListOfPhotos) { items.add(new Item(p.getId(),
			 * p.getTitle(), p.getTags())); }
			 */

			for (com.fivehundredpixels.fivehundredpixels.models.Photo p : my500pxList)
			{
				items.add(new Item(p.id, p.name, p.description));
			}
		}

		public void setCallback(Callback callback)
		{
			this.callback = callback;
		}

		@Override
		public int getCount()
		{
			// return items.size();
			// return mListOfPhotos.size() - 1;
			return my500pxList.size() - 1;
		}

		@Override
		public Object getItem(int position)
		{
			return position;
		}

		@Override
		public long getItemId(int position)
		{
			return items.get(position).getId();
		}

		@Override
		public boolean hasStableIds()
		{
			return true;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent)
		{
			ViewHolder holder;
			
			mPosition = position;
			
			if (convertView == null)
			{
				holder = new ViewHolder();
				convertView = inflater.inflate(R.layout.page, parent, false);

				holder.text = (TextView) convertView.findViewById(R.id.text);
				holder.firstPage = (ImageView) convertView
						.findViewById(R.id.first_page);

				holder.textTop = (TextView) convertView
						.findViewById(R.id.textTop);

				holder.textBottom = (TextView) convertView
						.findViewById(R.id.textBottom);

				holder.lastPage = (ImageView) convertView
						.findViewById(R.id.last_page);
				
				holder.firstPage.setOnClickListener(new View.OnClickListener()
				{
					
					@Override
					public void onClick(View v)
					{
						Intent intent = new Intent(MainActivity.this, PhotoDetailActivity.class);
						intent.putExtra("photoid", my500pxList.get(mPosition).id);
						startActivity(intent);
						
					}
				});
				
				
				holder.lastPage.setOnClickListener(new View.OnClickListener()
				{
					
					@Override
					public void onClick(View v)
					{
						Intent intent = new Intent(MainActivity.this, PhotoDetailActivity.class);
						intent.putExtra("photoid", my500pxList.get(mPosition).id);
						startActivity(intent);
						
					}
				});

				/*
				holder.firstPage.setOnClickListener(new View.OnClickListener()
				{
					
					@Override
					public void onClick(View v)
					{
						switch (v.getId())
						{
						case R.id.first_page:
							if (callback != null)
							{
								callback.onPageRequested(0);
							}
							break;
						case R.id.last_page:
							if (callback != null)
							{
								callback.onPageRequested(getCount() - 1);
							}
							break;
						}
					}
				});
				holder.lastPage.setOnClickListener(new View.OnClickListener()
				{
					@Override
					public void onClick(View v)
					{
						switch (v.getId())
						{
						case R.id.first_page:
							if (callback != null)
							{
								callback.onPageRequested(0);
							}
							break;
						case R.id.last_page:
							if (callback != null)
							{
								callback.onPageRequested(getCount() - 1);
							}
							break;
						}
					}
				});
				*/

				convertView.setTag(holder);
			} else
			{
				holder = (ViewHolder) convertView.getTag();
			}

			// TODO set a text with the id as well
			// holder.text.setText(items.get(position).getId()+":"+position);

			// holder.text.setText(" PageNumber : " + position);
			if (position < my500pxList.size())
			{
				/*
				 * holder.firstPage.setImageBitmap(mPhotoBitmapList.get(position)
				 * ); holder.lastPage.setImageBitmap(mPhotoBitmapList
				 * .get(position + 1));
				 */
				/*
				 * imageCacheLoader.DisplayImage(mListOfPhotos.get(position).
				 * getPhotoURL(), holder.firstPage);
				 * imageCacheLoader.DisplayImage
				 * (mListOfPhotos.get(position+1).getPhotoURL(),
				 * holder.lastPage);
				 * holder.textTop.setText(mListOfPhotos.get(position
				 * ).getTitle());
				 * holder.textBottom.setText(mListOfPhotos.get(position + 1)
				 * .getTitle()); holder.text.setText("Page " +(position+1) +
				 * " : " + mListOfPhotos.size());
				 */
				imageCacheLoader.DisplayImage(
						my500pxList.get(position).image_url, holder.firstPage);
				imageCacheLoader.DisplayImage(
						my500pxList.get(position + 1).image_url,
						holder.lastPage);
				holder.textTop.setText(my500pxList.get(position).name);
				holder.textBottom.setText(my500pxList.get(position + 1).name);
				holder.text.setText("Page " + (position + 1) + " : "
						+ my500pxList.size());
			}
			return convertView;
		}

		private class ViewHolder
		{
			TextView text;
			TextView textTop;
			TextView textBottom;
			ImageView firstPage;
			ImageView lastPage;
		}

		@Override
		public void onClick(View v)
		{
			switch (v.getId())
			{
			case R.id.first_page:
				if (callback != null)
				{
					callback.onPageRequested(0);
				}
				break;
			case R.id.last_page:
				if (callback != null)
				{
					callback.onPageRequested(getCount() - 1);
				}
				break;
			}
		}

		public void addItems(int amount)
		{
			for (int i = 0; i < amount; i++)
			{
				// items.add(new Item());
			}
			notifyDataSetChanged();
		}

		public void addItemsBefore(int amount)
		{
			for (int i = 0; i < amount; i++)
			{
				// items.add(0, new Item());
			}
			notifyDataSetChanged();
		}

	}

	private class DataLoadingTask extends AsyncTask<String, Integer, Integer>
	{
		@Override
		protected void onPreExecute()
		{
			// mListOfPhotos.clear();
			my500pxList.clear();
			mPhotoBitmapList.clear();
			mProgressBar = new ProgressDialog(MainActivity.this);
			mProgressBar.setCancelable(false);
			mProgressBar.setMessage("Downloading Feeds");
			mProgressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			mProgressBar.setProgress(0);
			mProgressBar.setMax(100);
			mProgressBar.show();
		}

		@Override
		protected Integer doInBackground(String... args)
		{
			String jsonFileUrl = args[0];
			try
			{
				read(jsonFileUrl);
			} catch (Exception ex)
			{
				Log.e(TAG, "-------" + ex.toString());
			}

			return null;

		}

		@Override
		protected void onProgressUpdate(Integer... values)
		{
			// Do nothing
		}

		@Override
		protected void onPostExecute(Integer result)
		{
			display();
		}

	}

	protected void read(String jsonFileUrl) throws IOException
	{
		/*
		 * mFlickrPhotoResponse = ObjectsReader
		 * .readFlickrPhotoResponse(jsonFileUrl);
		 * 
		 * 
		 * mListOfPhotos =
		 * mFlickrPhotoResponse.getPhotos().getFlickrPhotoList();
		 */
		
		String urlStr = jsonFileUrl;
		URL url = new URL(urlStr);
		URI uri = null;
		try
		{
			uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
		} catch (URISyntaxException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		url = uri.toURL();

		my500pxList = DataManager.getInstance().fetchPhotosByGet(this,url.toString(),
				true);
		
		Log.d(TAG, "-------------------clean url : " + url.toString());
		
		/*
		 * 
		 * int progress = 0; int progressIncrement = mProgressBar.getMax() /
		 * mListOfPhotos.size();
		 * 
		 * if (mListOfPhotos != null) { Log.d(TAG,
		 * mListOfPhotos.get(0).getTitle()); Log.d(TAG,
		 * mListOfPhotos.get(0).getPhotoURL()); } else Log.d(TAG,
		 * "Null probably");
		 * 
		 * // Getting whole PhotoURL list and Generating BITMAPs for Thumbnails
		 * for (int i = 0; i < mListOfPhotos.size(); i++) { Log.d(TAG,
		 * mListOfPhotos.get(i).getPhotoURL());
		 * 
		 * try { URL myFileUrl = new URL(mListOfPhotos.get(i).getPhotoURL(
		 * PhotoSize.t)); HttpURLConnection conn = (HttpURLConnection) myFileUrl
		 * .openConnection(); conn.setDoInput(true); conn.connect();
		 * mPhotoBitmapList.add(BitmapFactory.decodeStream(conn
		 * .getInputStream())); mMap.put(mListOfPhotos.get(i),
		 * mPhotoBitmapList.get(i));
		 * 
		 * // Display Progress progress += progressIncrement;
		 * mProgressBar.setProgress(progress); } catch (MalformedURLException e)
		 * { e.printStackTrace(); } catch (IOException e) { e.printStackTrace();
		 * } }
		 */
	}

	protected void display()
	{
		// MyCustomAdapter adapter = new MyCustomAdapter(this,
		// R.layout.activity_list_row, mListOfPhotos);
		// mListView.setAdapter(adapter);
		// mProgressBar.dismiss();

		mAdapter = new FlipAdapter(this);
		mAdapter.setCallback(this);
		mFlipView.setAdapter(mAdapter);
		mProgressBar.dismiss();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mFlipView = (FlipView) findViewById(R.id.flip_view);

		setupNavigationDrawer(savedInstanceState);

		// mAdapter = new FlipAdapter(this);
		// mAdapter.setCallback(this);
		// mFlipView.setAdapter(mAdapter);

		mFlipView.setOnFlipListener(this);
		mFlipView.peakNext(false);
		mFlipView.setOverFlipMode(OverFlipMode.GLOW);
		mFlipView.setEmptyView(findViewById(R.id.empty_view));
		mFlipView.setOnOverFlipListener(this);

		imageCacheLoader = new ImageCacheLoader(this);

		// new DataLoadingTask().execute(FeaturesConfiguration.flickrURL);

		new DataLoadingTask().execute(FeaturesConfiguration.popularURL);

	}

	/* The click listner for ListView in the navigation drawer */
	private class DrawerItemClickListener implements
			ListView.OnItemClickListener
	{
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id)
		{
			selectItem(position);
		}
	}

	private void selectItem(int position)
	{
		// update the main content by replacing fragments
		Fragment fragment = new PlanetFragment();
		Bundle args = new Bundle();
		args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
		fragment.setArguments(args);

		// FragmentManager fragmentManager = getFragmentManager();
		// fragmentManager.beginTransaction().replace(R.id.content_frame,
		// fragment).commit();

		/*
		 * new DataLoadingTask().execute(FeaturesConfiguration.flickrSearchURL +
		 * "&tags=" + mPlanetTitles[position]);
		 */

		new DataLoadingTask()
				.execute(FeaturesConfiguration.popularBaseURL
						+ mPlanetTitles[position]
						+ ",Journalism&consumer_key=pxRXc9xTQPKLhk65bwbD3H85GbiTjZgbNOavheHF");

		// update selected item and title, then close the drawer
		mDrawerList.setItemChecked(position, true);
		setTitle(mPlanetTitles[position]);
		mDrawerLayout.closeDrawer(mDrawerList);
	}

	protected void setupNavigationDrawer(Bundle savedInstanceState)
	{
		mTitle = mDrawerTitle = getTitle();
		mPlanetTitles = getResources().getStringArray(R.array.planets_array);
		mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
		mDrawerList = (ListView) findViewById(R.id.left_drawer);

		// set a custom shadow that overlays the main content when the drawer
		// opens
		mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
				GravityCompat.START);
		// set up the drawer's list view with items and click listener
		mDrawerList.setAdapter(new ArrayAdapter<String>(this,
				R.layout.drawer_list_item, mPlanetTitles));
		mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

		// enable ActionBar app icon to behave as action to toggle nav drawer
		getActionBar().setDisplayHomeAsUpEnabled(true);
		getActionBar().setHomeButtonEnabled(true);

		// ActionBarDrawerToggle ties together the the proper interactions
		// between the sliding drawer and the action bar app icon
		mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
		mDrawerLayout, /* DrawerLayout object */
		R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
		R.string.drawer_open, /* "open drawer" description for accessibility */
		R.string.drawer_close /* "close drawer" description for accessibility */
		)
		{
			public void onDrawerClosed(View view)
			{
				getActionBar().setTitle(mTitle);
				invalidateOptionsMenu(); // creates call to
											// onPrepareOptionsMenu()
			}

			public void onDrawerOpened(View drawerView)
			{
				getActionBar().setTitle(mDrawerTitle);
				invalidateOptionsMenu(); // creates call to
											// onPrepareOptionsMenu()
			}
		};
		mDrawerLayout.setDrawerListener(mDrawerToggle);

		if (savedInstanceState == null)
		{
			// selectItem(0);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		getMenuInflater().inflate(R.menu.menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		// The action bar home/up action should open or close the drawer.
		// ActionBarDrawerToggle will take care of this.
		if (mDrawerToggle.onOptionsItemSelected(item))
		{
			return true;
		}
		// Handle action buttons
		switch (item.getItemId())
		{
		case R.id.action_websearch:
			// create intent to perform web search for this planet
			Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
			intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
			// catch event that there's no activity to handle intent
			if (intent.resolveActivity(getPackageManager()) != null)
			{
				startActivity(intent);
			} else
			{
				Toast.makeText(this, R.string.app_not_available,
						Toast.LENGTH_LONG).show();
			}
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)
		{
			event.startTracking();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	public boolean onKeyUp(int keyCode, KeyEvent event)
	{
		if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
				&& !event.isCanceled())
		{
			// *** DO ACTION HERE ***
			boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
			if (drawerOpen)
			{
				mDrawerLayout.closeDrawers();
			} else
			{
				mDrawerLayout.openDrawer(mDrawerList);
			}

			return true;
		}
		return super.onKeyUp(keyCode, event);
	}

	@Override
	public void onPageRequested(int page)
	{
		mFlipView.smoothFlipTo(page);
	}

	@Override
	public void onFlippedToPage(FlipView v, int position, long id)
	{
		// Toast.makeText(getBaseContext(), "Page: "+position,
		// Toast.LENGTH_SHORT).show();
		if (position > mFlipView.getPageCount() - 3
				&& mFlipView.getPageCount() < 30)
		{
			mAdapter.addItems(5);
		}
	}

	@Override
	public void onOverFlip(FlipView v, OverFlipMode mode,
			boolean overFlippingPrevious, float overFlipDistance,
			float flipDistancePerPage)
	{
		Log.i(TAG, "overflip " + " overFlipDistance = " + overFlipDistance);
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig)
	{
		super.onConfigurationChanged(newConfig);
		Log.d(TAG, "config changed" + newConfig.toString());
		// Checks the orientation of the screen
		if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
		{
			// Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
		} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
		{
			// Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
		}

	}

}
